package remote

import (
	"log"
	"net"

	"github.com/sdttttt/sraft/codec"
)

const (
	ConnectType = "tcp"
)

type MasterExchangeTCP struct {
	l net.Listener

	pool map[string]net.Conn
}

type SlaveExchangeTCP struct {
	c net.Conn
}

func (e *SlaveExchangeTCP) Send(res interface{}) {
	b := codec.Encode(res)
	if _, err := e.c.Write(b); err != nil {
		log.Fatalln(err)
	}
}

func (e *SlaveExchangeTCP) Recv() interface{} {
	var bs []byte

	if _, err := e.c.Read(bs); err != nil {
		log.Fatalln(err)
	}

	return codec.Decode(bs)
}

func (m *MasterExchangeTCP) NewConn() net.Conn {
	c, err := m.l.Accept()
	if err != nil {
		log.Fatalln(err)
	}
	m.pool[c.RemoteAddr().String()] = c

	return c
}

func NewMasterExchangeTCP(port string) *MasterExchangeTCP {
	l, err := net.Listen(ConnectType, port)

	if err != nil {
		panic(err)
	}

	return &MasterExchangeTCP{
		l:    l,
		pool: make(map[string]net.Conn),
	}
}

func NewSlaveExchangeTCP(addr string) *SlaveExchangeTCP {
	c, err := net.Dial(ConnectType, addr)
	if err != nil {
		panic(err)
	}

	return &SlaveExchangeTCP{
		c: c,
	}
}
